package ntd.util.frame.action.com;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import ntd.action.ActionAbs;
import ntd.action.ActionManager;
import ntd.action.bo.ActionInBo;
import ntd.action.bo.ActionInfo;
import ntd.action.bo.ActionOutBo;
import ntd.util.config.common.exception.ComException;
import ntd.util.frame.data.factory.FactoryData;
import ntd.util.frame.data.tool.ToolMysql;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class ActionComResourceAllocation extends ActionAbs {

    @Override
    public ActionInfo info() {
        return new ActionInfo("用户资源分配", "action-account-com-resource-allocation", new ActionComResourceAllocation());
    }

    @Override
    public ActionOutBo handle() {
        //数据库
        ToolMysql toolMysql = new ToolMysql(FactoryData.dataSource());

        // 用户标识
        String dataCode = actionInBo.getDataCode();
        if (StrUtil.isBlank(dataCode)) {
            throw new ComException("用户标识不能为空...");
        }
        // 资源列表
        List<String> resIds = JSONUtil.toList(actionInBo.getDataStr(), String.class);
        List<Entity> accountMenus;
        try {
            if (resIds.size() > 0) {
                // 查询用户资源
                List<Entity> currentResources = toolMysql.db.findBy("account_menu", "account_id", dataCode);
                // 比对用户资源 - 需删除资源ids
                List<Entity> delResourceIds = CollectionUtil.filter(CollectionUtil.newArrayList(currentResources), entity -> !resIds.contains(entity.getStr("resource_id")));
                List<String> delResources = CollStreamUtil.toList(delResourceIds, entity -> entity.getStr("id"));
                // 删除对应资源
                if (CollectionUtil.isNotEmpty(delResources)) {
                    toolMysql.db.del("account_menu", "id", delResources);
                }

                // 比对用户资源 - 需添加资源ids
                List<String> resourceIds = CollStreamUtil.toList(currentResources, entity -> entity.getStr("resource_id"));
                List<String> addResourceIds = CollectionUtil.filter(resIds, s -> !resourceIds.contains(s));
                if (CollectionUtil.isNotEmpty(addResourceIds)) {
                    // 查询资源对应数据
                    List<Entity> entities = toolMysql.db.find(new Entity("common_resource").set("id", addResourceIds));
                    // 重新分配用户资源
                    for (int i = 0; i < entities.size(); i++) {
                        Entity entityResource = entities.get(i);
                        Entity entityAccountMenu = Entity.create("account_menu");
                        entityAccountMenu.set("resource_id", entityResource.getStr("id"));
                        entityAccountMenu.set("name", entityResource.getStr("name"));
                        entityAccountMenu.set("icon", entityResource.getStr("icon"));
                        entityAccountMenu.set("account_id", dataCode);
                        ActionManager.get("action-table-sync").getAction().execute(new ActionInBo().setDataCode("account_menu").setDataStr(JSONUtil.toJsonStr(entityAccountMenu)));
                    }
                }
            }
            // 查询用户对应资源列表
            accountMenus = toolMysql.db.find(new Entity("account_menu").set("account_id", dataCode));
            List<String> resourceIds = CollStreamUtil.toList(accountMenus, entity -> entity.getStr("resource_id"));
            if (CollectionUtil.isNotEmpty(resourceIds)) {
                List<Entity> resources = toolMysql.db.find(new Entity("common_resource").set("id", resourceIds));
                Map<String, Entity> resourceMap = CollStreamUtil.toIdentityMap(resources, entity -> entity.getStr("id"));
                for (Entity accountMenu : accountMenus) {
                    Entity entity = resourceMap.get(accountMenu.getStr("resource_id"));
                    accountMenu.set("com_resource", entity);
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return new ActionOutBo(accountMenus);
    }
}
